package com.kobeliu.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.kobeliu.base.BaseInfoProperties;
import com.kobeliu.enums.ActiveTime;
import com.kobeliu.enums.EduEnum;
import com.kobeliu.enums.JobStatus;
import com.kobeliu.pojo.Industry;
import com.kobeliu.pojo.ResumeEducation;
import com.kobeliu.pojo.ResumeProjectExp;
import com.kobeliu.pojo.ResumeWorkExp;
import com.kobeliu.pojo.bo.*;
import com.kobeliu.pojo.eo.SearchResumesEO;
import com.kobeliu.pojo.vo.ResumeExpectVO;
import com.kobeliu.pojo.vo.ResumeVO;
import com.kobeliu.result.GraceJSONResult;
import com.kobeliu.service.*;
import com.kobeliu.utils.PagedGridResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

@RestController
@RequestMapping("resume")
@Slf4j
public class ResumeController extends BaseInfoProperties {


    @Autowired
    private ResumeService resumeService;
    @Autowired
    private ResumeSearchService resumeSearchService;
    @Autowired
    private ResumeWorkExpService workExpService;

    @Autowired
    private ResumeProjectExpService projectExpService;

    @Autowired
    private ResumeEducationService educationService;

    @Autowired
    private ResumeExpectService expectService;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @PostMapping("init")
    public GraceJSONResult init(@RequestParam("userId")String userId){

        String resumeId = resumeService.initResume(userId);

        return GraceJSONResult.ok(resumeId);
    }

    @PostMapping("queryMyResume1")
    public GraceJSONResult queryMyResume1(@RequestParam("userId")String userId){

        ResumeVO pending = new ResumeVO();

        //1.拿取resume数据
        ResumeVO resumeVO = resumeService.getByUserId(userId);
        BeanUtils.copyProperties(resumeVO,pending);

        //2.拿取workExp的数据
        List<ResumeWorkExp> workExps = workExpService.getWorkExps(userId);
        pending.setWorkExpList(workExps);

        //3.拿取ResumeProjectExp数据
        List<ResumeProjectExp>  projectExpList = projectExpService.getProjectExps(userId);
        pending.setProjectExpList(projectExpList);

        //4.拿取教育经历
        List<ResumeEducation> educationList = educationService.getEduExps(userId);
        pending.setEducationList(educationList);

        //由于数据量大，且不易变动，采用redis缓存


        return GraceJSONResult.ok(pending);
    }

    /**
     * 串行改并发
     * @param userId
     * @return
     */
    @PostMapping("queryMyResume2")
    public GraceJSONResult queryMyResume2(@RequestParam("userId")String userId) throws ExecutionException, InterruptedException {

        long start = System.currentTimeMillis();
        //由于数据量大，且不易变动，采用redis缓存
        String resumeJson = redis.get(REDIS_RESUME_INFO + ":" + userId);
        if(StringUtils.isNotBlank(resumeJson)){
            ResumeVO vo = new Gson().fromJson(resumeJson,ResumeVO.class);
            return GraceJSONResult.ok(vo);
        }

        CompletableFuture<ResumeVO> future = CompletableFuture.supplyAsync(()->{
            //1.拿取resume数据
            return resumeService.getByUserId(userId);

        },threadPoolExecutor);

        //阻塞等待
        ResumeVO pending = future.get();

        CompletableFuture<Void> workFuture = CompletableFuture.runAsync(()->{
            //2.拿取workExp的数据
            List<ResumeWorkExp> workExps = workExpService.getWorkExps(userId);
            pending.setWorkExpList(workExps);
        },threadPoolExecutor);

        CompletableFuture<Void> projectFuture = CompletableFuture.runAsync(()->{
            //3.拿取ResumeProjectExp数据
            List<ResumeProjectExp>  projectExpList = projectExpService.getProjectExps(userId);
            pending.setProjectExpList(projectExpList);
        },threadPoolExecutor);

        CompletableFuture<Void> eduFuture = CompletableFuture.runAsync(()->{
            //4.拿取教育经历
            List<ResumeEducation> educationList = educationService.getEduExps(userId);
            pending.setEducationList(educationList);

        },threadPoolExecutor);

        //三个编排任务要全部完成
        CompletableFuture<Void> allOf = CompletableFuture.allOf(workFuture, projectFuture, eduFuture);

        //阻塞等待全部完成
        allOf.get();

        //存入缓存
        redis.set(REDIS_RESUME_INFO+":"+userId,new Gson().toJson(pending),60);

        long end = System.currentTimeMillis();
        long sum = end-start;
        log.info("消耗的时间为：{}",sum);

        return GraceJSONResult.ok(pending);
    }

    @PostMapping("queryMyResume")
    public GraceJSONResult queryMyResume(@RequestParam("userId")String userId) throws ExecutionException, InterruptedException {

        ResumeVO pending = resumeService.getByUserId(userId);
//        ResumeVO pending = resumeSearchService.getByUserId(userId);
        return GraceJSONResult.ok(pending);
    }

    @PostMapping("modify")
    public GraceJSONResult modify(@RequestBody EditResumeBO bo){

        resumeService.updateResume(bo);
        return GraceJSONResult.ok();
    }

    /**
     * 修改/插入 一条工作经验
     * @param bo
     * @return
     */
    @PostMapping("editWorkExp")
    public GraceJSONResult editWorkExp(@RequestBody EditWorkExpBO bo){

        workExpService.editWorkExp(bo);

        return GraceJSONResult.ok();

    }

    /**
     * 修改/插入 一条项目经验
     * @param bo
     * @return
     */
    @PostMapping("editProjectExp")
    public GraceJSONResult editProjectExp(@RequestBody EditProjectExpBO bo){

        projectExpService.editProjectExp(bo);

        return GraceJSONResult.ok();

    }

    /**
     * 修改/插入 一条教育经历
     * @param bo
     * @return
     */
    @PostMapping("editEducation")
    public GraceJSONResult editEdu(@RequestBody EditEducationBO bo){

        educationService.editEduExp(bo);

        return GraceJSONResult.ok();

    }

    /**
     * 根据传过来的userId和workEXpId 查询经历
     * @param workExpId
     * @param userId
     * @return
     */
    @PostMapping("getWorkExp")
    public GraceJSONResult getWorkExp(String workExpId,String userId){

        ResumeWorkExp workExp = workExpService.getWorkExp(workExpId,userId);

        return GraceJSONResult.ok(workExp);
    }

    /**
     * 根据传过来的userId和projectExpId 查询经历
     * @param projectExpId
     * @param userId
     * @return
     */
    @PostMapping("getProjectExp")
    public GraceJSONResult getProjectExp(String projectExpId,String userId){

        ResumeProjectExp projectExp = projectExpService.getProjectExp(projectExpId,userId);

        return GraceJSONResult.ok(projectExp);
    }

    /**
     * 根据传过来的userId和eduId 查询经历
     * @param eduId
     * @param userId
     * @return
     */
    @PostMapping("getEducation")
    public GraceJSONResult getEducation(String eduId,String userId){

        ResumeEducation eduExp = educationService.getEduExp(eduId,userId);

        return GraceJSONResult.ok(eduExp);
    }

    @PostMapping("deleteProjectExp")
    public GraceJSONResult deleteProjectExp(String projectExpId,String userId){
        projectExpService.deleteByProIdAndUserId(projectExpId,userId);
        return GraceJSONResult.ok();
    }

    @PostMapping("deleteEducation")
    public GraceJSONResult deleteEducation(String eduId,String userId){
        educationService.deleteByEduIdAndUserId(eduId,userId);
        return GraceJSONResult.ok();
    }

    @PostMapping("deleteWorkExp")
    public GraceJSONResult deleteWorkExp(String workExpId,String userId){
        workExpService.deleteByWorkExpIdAndUserId(workExpId,userId);
        return GraceJSONResult.ok();
    }

    @PostMapping("editJobExpect")
    public GraceJSONResult editJobExpect(@RequestBody EditResumeExpectBO bo){

        expectService.save(bo);

        return GraceJSONResult.ok();
    }

    /**
     * 获取期望list
     * @param resumeId
     * @param userId
     * @return
     */
    @PostMapping("getMyResumeExpectList")
    public GraceJSONResult getMyResumeExpectList(String resumeId,String userId){

        List<ResumeExpectVO> vos = new ArrayList<>();
        String listJson = redis.get(REDIS_RESUME_EXPECT + ":" + userId);
        if(StringUtils.isNotBlank(listJson)){
            vos =  new Gson().fromJson(listJson,new TypeToken<List<ResumeExpectVO>>() {}.getType());
        }else{
            vos = expectService.getList(resumeId,userId, JobStatus.OPEN);
            redis.set(REDIS_RESUME_EXPECT + ":" + userId,new Gson().toJson(vos));
        }

        return GraceJSONResult.ok(vos);
    }

    @PostMapping("deleteMyResumeExpect")
    public GraceJSONResult deleteMyResumeExpect(String resumeExpectId,String userId){

        expectService.delete(resumeExpectId,userId);

        return GraceJSONResult.ok();
    }

    @SentinelResource(value = "test/refresh",
            blockHandler = "blockHandler",
    fallback = "fallBackerForRefresh")
    @PostMapping("refresh")
    public GraceJSONResult refresh(String userId,String resumeId){

        if(StringUtils.isBlank(userId) || StringUtils.isBlank(resumeId)){
            return GraceJSONResult.error();
        }
        //resumeService.refresh(userId,resumeId);
        resumeSearchService.transformAndFlush2Es(userId);
        return GraceJSONResult.ok();
    }

    //原方法被降级/限流/保护时调用
    public GraceJSONResult blockHandler(String userId,String resumeId){
        return GraceJSONResult.errorMsg("失败的人生重新开始--");
    }

    //原方法异常出现使用的方法
    public GraceJSONResult fallBackerForRefresh(String userId,String resumeId){
        return GraceJSONResult.ok("刷新成功");
    }

    @PostMapping("searchResumes")
    public GraceJSONResult searchResumes(@RequestBody SearchResumesBO searchResumesBO,
                                         Integer page,
                                         Integer limit){
        if(page == null) page=1;
        if(limit == null) limit=10;
        //搜索的简历活跃度
        String activeTime = searchResumesBO.getActiveTime();
        Integer activeTimes = ActiveTime.getActiveTimes(activeTime);
        searchResumesBO.setActiveTime(activeTime);

        //搜索的学历及以上
        String edu = searchResumesBO.getEdu();
        Integer eduIndex = EduEnum.getEduIndex(edu);
        List<String> eduList = EduEnum.getEduList(eduIndex);
        searchResumesBO.setEduList(eduList);

//        PagedGridResult result = resumeService.searchResumes(searchResumesBO,page,limit);
        PagedGridResult result = resumeSearchService.searchResumesByEs(searchResumesBO,page,limit);

        return GraceJSONResult.ok(result);

    }



}
